package com.example.oss.service.impl;

import java.util.Date;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.example.oss.service.AliFileUploadService;
import com.example.oss.vo.AliOssTokenResVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class AliFileUploadServiceImpl implements AliFileUploadService {

    @Value("${oss.accessId}")
    private String accessId;
    @Value("${oss.accessKey}")
    private String accessKey;
    @Value("${oss.endpoint}")
    private String endpoint;
    @Value("${oss.bucket}")
    private String bucket;
    @Value("${oss.host}")
    private String host;
    @Value("${oss.callbackUrl}")
    private String callbackUrl;
    @Value("${oss.dir}")
    private String dir;


    @Override
    public AliOssTokenResVO getUploadToken(Integer uploadType) throws Exception {

        // 创建OSSClient实例。
        OSS client = new OSSClientBuilder().build(endpoint, accessId, accessKey);

        try {
            long expireTime = 300;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);

            //存储数据封装
            AliOssTokenResVO aliOssTokenResVO = new AliOssTokenResVO();
            aliOssTokenResVO.setAccessid(accessId);
            aliOssTokenResVO.setPolicy(encodedPolicy);
            aliOssTokenResVO.setSignature(postSignature);
            aliOssTokenResVO.setDir(dir);
            aliOssTokenResVO.setHost(host);
            aliOssTokenResVO.setExpire(String.valueOf(expireEndTime / 1000));

            JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", callbackUrl);
            jasonCallback.put("callbackBody",
                    "filename=${object}&size=${size}&mimeType=${mimeType}&resourceType=${" + uploadType + "}");
            jasonCallback.put("callbackBodyType", "application/json");
            log.info("回调callback：" + jasonCallback.toString());
            String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
            aliOssTokenResVO.setCallback(base64CallbackBody);
            //
            return aliOssTokenResVO;
        } catch (Exception e) {
            log.error("获取OSS直传签名异常: {}", e.getMessage());
            throw new Exception("生成凭证失败");
        } finally {
            client.shutdown();
        }
    }

}
